/**************************************************************************************************
 * @file        logger.h
 * @brief       跨平台日志系统API封装，支持Windows、Linux、macOS等系统的日志记录功能
 * @details     提供统一的日志接口，包括日志级别控制、文件输出、日志轮转等功能。
 *
 * @author      taoist.luo
 * @version     1.0.0
 * @date        2024-09
 *
 * Copyright (c) 2024 taoist.luo (https://gitee.com/harmonyluo(https://blog.csdn.net/harmonyluo))
 *
 * MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *************************************************************************************************/
#pragma once

#include <fstream>
#include <memory>
#include <mutex>
#include <sstream>
#include <string>

// 日志级别定义
typedef enum log_level_e {
    OS_DEBUG = 0,
    OS_INFO,
    OS_WARNING,
    OS_ERROR,
    OS_FATAL
} log_level_e;

class logger
{
public:
    static logger* instance();
    static void release();

    void setLogLevel(log_level_e level);
    log_level_e getLogLevel();
    void setLogFile(const std::string& file);
    void setMaxFileSize(size_t size);

    void log(log_level_e level, const std::string& message, const char* file = "", int line = 0);
    void log2(log_level_e level, const std::string& message);
    void log3(log_level_e level, const std::string& message, const char* file = "", const char* func = "",
              int line = 0);
    void logFormatted(log_level_e level, const char* file, int line, const char* format, ...);
    void logFormatted2(log_level_e level, const char* format, ...);
    void logFormatted3(log_level_e level, const char* file, const char* func, int line, const char* format, ...);

private:
    logger();
    ~logger();

    std::string levelToString(log_level_e level);
    std::string levelToColor(log_level_e level);
    void rotateLog();

    static logger* m_instance;
    std::unique_ptr<std::ofstream> m_log_file;
    std::mutex m_mutex;
    log_level_e m_log_level;
    size_t m_max_file_size;
    std::string m_file_path;
};



// 添加流式日志支持
class LogStream
{
public:
    LogStream(logger* logger, log_level_e level, const char* file = "", int line = 0) :
        m_logger(logger),
        m_level(level),
        m_file(file),
        m_line(line)
    {
    }

    template <typename T>
    LogStream& operator<<(const T& value)
    {
        m_message << value;
        return *this;
    }

    ~LogStream()
    {
        if (!m_message.str().empty()) {
            m_logger->log(m_level, m_message.str(), m_file.c_str(), m_line);
        }
    }

private:
    logger* m_logger;
    log_level_e m_level;
    std::string m_file;
    int m_line;
    std::ostringstream m_message;
};

// 日志宏定义 - 支持格式化输出
#define LOGD(format, ...)  logger::instance()->logFormatted(OS_DEBUG, __FILE__, __LINE__, format, ##__VA_ARGS__)
#define LOGI(format, ...)  logger::instance()->logFormatted(OS_INFO, __FILE__, __LINE__, format, ##__VA_ARGS__)
#define LOGW(format, ...)  logger::instance()->logFormatted(OS_WARNING, __FILE__, __LINE__, format, ##__VA_ARGS__)
#define LOGE(format, ...)  logger::instance()->logFormatted(OS_ERROR, __FILE__, __LINE__, format, ##__VA_ARGS__)
#define LOGF(format, ...)  logger::instance()->logFormatted(OS_FATAL, __FILE__, __LINE__, format, ##__VA_ARGS__)

#define LOGPD(format, ...) logger::instance()->logFormatted2(OS_DEBUG, format, ##__VA_ARGS__)
#define LOGPI(format, ...) logger::instance()->logFormatted2(OS_INFO, format, ##__VA_ARGS__)
#define LOGPW(format, ...) logger::instance()->logFormatted2(OS_WARNING, format, ##__VA_ARGS__)
#define LOGPE(format, ...) logger::instance()->logFormatted2(OS_ERROR, format, ##__VA_ARGS__)
#define LOGPF(format, ...) logger::instance()->logFormatted2(OS_FATAL, format, ##__VA_ARGS__)

// 流式日志宏定义
#define LOGSD  LogStream(logger::instance(), OS_DEBUG, __FILE__, __LINE__)
#define LOGSI  LogStream(logger::instance(), OS_INFO, __FILE__, __LINE__)
#define LOGSW  LogStream(logger::instance(), OS_WARNING, __FILE__, __LINE__)
#define LOGSE  LogStream(logger::instance(), OS_ERROR, __FILE__, __LINE__)
#define LOGSF  LogStream(logger::instance(), OS_FATAL, __FILE__, __LINE__)

#define LOGPSD LogStream(logger::instance(), OS_DEBUG)
#define LOGPSI LogStream(logger::instance(), OS_INFO)
#define LOGPSW LogStream(logger::instance(), OS_WARNING)
#define LOGPSE LogStream(logger::instance(), OS_ERROR)
#define LOGPSF LogStream(logger::instance(), OS_FATAL)

void printMemory(const std::string& info = "");
#if 0
    #define TRACE(format, ...) \
        logger::instance()->logFormatted3(OS_DEBUG, __FILE__, __FUNCTION__, __LINE__, format, ##__VA_ARGS__)
#else
    #define TRACE void
#endif